package ldh.common.testui.vo;

import lombok.Data;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.List;

@Data
public class VarModel {

    private String varName;
    private Class<?> clazz;
    private Type type;

    private transient Class<?> beanClazz;  // 实际类型，主要针对泛型
    private transient Class<?> keyClazz; // 泛型map，中key的实际类型
    private transient boolean isManyDatas = false;

    public static final List<Class> KEY_CLASS = Arrays.asList(Integer.class, Long.class, String.class);

    public boolean isBean() {
        boolean result = clazz.toString().equals(type.toString()) && !clazz.isArray();
        if (result) beanClazz = clazz;
        return result;
    }

    public boolean isArray() {
        boolean result =  clazz.isArray() && !(type instanceof ParameterizedType);
        if (result) {
            beanClazz = clazz.getComponentType();
            isManyDatas = true;
        }
        return result;
    }

    public boolean isListOrSet() {
        if(type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;

            Type[] types = parameterizedType.getActualTypeArguments();
            if (types.length == 1) { // 不是map
                if (!(types[0] instanceof ParameterizedType)) {  // 不支持多层嵌套
                    beanClazz = (Class) types[0];
                    isManyDatas = true;
                    return true;
                }
            }
        }
        return false;
    }

    public boolean isMap() {
        if(type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;
            Type[] types = parameterizedType.getActualTypeArguments();
            if (types.length == 2) { // 是map
                if (!(types[0] instanceof ParameterizedType) && !(types[1] instanceof ParameterizedType)) {  // 不支持多层嵌套
                    keyClazz = (Class<?>) types[0];
                    if (KEY_CLASS.contains(keyClazz) || keyClazz.isEnum()) {
                        beanClazz = (Class<?>) types[1];
                        return true;
                    }
                }
            }
        }
        return false;
    }

    public boolean isListMap() {
        if(type instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) type;
            Type[] types = parameterizedType.getActualTypeArguments();
            if (types.length == 1) { // 不是map
                if ((types[0] instanceof ParameterizedType)) {  // 不支持多层嵌套
                    ParameterizedType parameterizedType1 = (ParameterizedType) types[0];
                    Type[] types2 = parameterizedType1.getActualTypeArguments();
                    if (types2.length == 2) { // map
                        if (!(types2[0] instanceof ParameterizedType) && !(types2[1] instanceof ParameterizedType)) {  // 不支持多层嵌套
                            keyClazz = (Class<?>) types2[0];
                            if (KEY_CLASS.contains(keyClazz) || keyClazz.isEnum()) {
                                beanClazz = (Class<?>) types2[1];
                                isManyDatas = true;
                                return true;
                            }
                        }
                    }
                }
            }
        }
        return false;
    }

    public Class getBeanClazz() {
        if (beanClazz == null) {
            isBean(); isMap(); isListMap(); isListOrSet(); isArray();
        }
        return beanClazz;
    }

    public Class getKeyClazz() {
        if (keyClazz == null) {
            getBeanClazz();
        }
        return keyClazz;
    }

}
